# 可忽略参数
def test(a, b=None, c=2):
    print(a, b, c)


# def test2(a=None, b  ):报错
#     print(a, b )

# 可以定义
def test2(a=None, b=None, c=None):
    print(a, b, c)


test(1, 2, 3)
test2(1, 2, 3)
test(1)
test2(1)


# 多参数
# 用*args表示该函数可以有多个参数
# 这些参数统称为args，是一个元组
# 调用时，可以不传参数
# 如果*args和其他关键字参数一起使用，在调用时，一般需要指定关键字参数赋值


def func(str, *args, ):
    print(str, args)


# 这时默认会将第一个参数赋值给str，其他参数属于args
func("一个字符串", 2, 3, 4, )


# def func(*args, str):
#     pass
# 这里需要指定str参数的值，否则会以为所有参数都是args的数据
# func(2, 3, 4, str="一个字符串")


# 多参数
# 用**kwargs表示一组关键字参数。
# 每个参数需要有一个对应的参数名,这些参数会以字典的形式使用
# 如果还有已知参数，已知参数需要写在前面
def fn2(str, **kwargs):
    print(str, kwargs)
    for k, v in kwargs.items():
        print(k, v)


# **kwargs需要使用  参数名=值 的方式传递参数
fn2(str="xxxx", a=1, b=2, c=3)


# 定义函数，计算该函数所有参数之和
def sum(*args):
    sum = 0
    for arg in args:
        sum += arg
    return sum


print(sum(1, 2, 3, 7))


# 匿名函数
# 普通函数定义
def hello():
    return "hello world"


print(hello())
print(type(hello))
# lambda: "hello world"是一个匿名函数
# 这里的xxx表示用一个变量接收这个匿名函数
xxx = lambda: "hello world"
print(type(xxx))
print(xxx())

# 如果匿名函数有参数，在lambda后定义参数
res = lambda x: x ** 2
print(res(5))
# 多个参数用逗号隔开
res = lambda a, b: a + b
print(res(5, 9))


